from typing import Optional

from src.database.core import async_session_maker
from sqlalchemy import update
from fastapi import HTTPException


from src.database.models import User
from src.user_service.schemas import (
    Update_form,
    My_account
)

from src.database.my_crud import My_crud
from src.security_module import pwd_context
from src.user_service.service.auth import raise_401_error

user_crud = My_crud(User)


class User_service:

    async def get_account(self, accountId: int, user_id: Optional[int]):
        await raise_401_error(user_id)
        print(accountId)

        if not await user_crud.exist([User.id == user_id]):
            raise HTTPException(
                status_code=404,
                detail="account not exists"
            )
        return await user_crud.get([User.id == accountId], My_account)

    async def putch_account(
        self,
        accountId: int,
        data_to_update: Update_form,
        user_id: Optional[int]
    ):
        await raise_401_error(user_id)

        if not await user_crud.exist([User.id == user_id]):
            raise HTTPException(
                status_code=403,
                detail="account not exists"
            )

        # if user_id != accountId:
        #     raise HTTPException(
        #         status_code=403,
        #         detail="account not belong to the user"
        #     )

        if data_to_update.email:
            if not await user_crud.exist([User.id == user_id]):
                raise HTTPException(
                    status_code=409,
                    detail="email belong to another user"
                )

        if data_to_update.password:
            data_to_update.password = pwd_context.hash(data_to_update.password)
        new_data = data_to_update.model_dump(exclude_none=True)

        query_patch = (
            update(User)
            .where(User.id == accountId)
            .values(**new_data)
        )

        async with async_session_maker() as session:
            await session.execute(query_patch)
            await session.commit()

        return await user_crud.patch(
            [User.id == accountId],
            new_data=new_data,
            Output_model=My_account
        )

    async def delete_account(self, accountId: int, user_id: Optional[int]):
        await raise_401_error(user_id)

        if not await user_crud.exist([User.id == user_id]):
            raise HTTPException(
                status_code=403,
                detail="account not exists"
            )

        await user_crud.remove([User.id == accountId])
